package com.echo.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.echo.context.AiUserIdContext;
import com.echo.dto.RegisterDTO;
import com.echo.dto.WisUserDTO;
import com.echo.entity.*;
import com.echo.enumeration.LoginTypeEnum;
import com.echo.enumeration.RoleEnum;
import com.echo.mapper.*;
import com.echo.properties.JwtProperties;
import com.echo.qo.LoginQo;
import com.echo.service.IWisUserService;
import com.echo.utils.JwtUtils;
import com.echo.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author echo
 * @since 2024-10-31
 */
@Slf4j
@Service
public class WisUserServiceImpl extends ServiceImpl<WisUserMapper, WisUser> implements IWisUserService {
    @Autowired
    private WisUserMapper WisuserMapper;
    @Autowired
    JwtProperties jwtProperties;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionPageMapper permissionPageMapper;
    @Autowired
    private PermissionMapper perssionMapper;
    @Autowired
    private UserMapper aiUserMapper;
    @Override
    public WisUser register(RegisterDTO registerDTO) {
        try {
            WisUser wisUser = new WisUser();
            wisUser.setUserId(IdUtil.simpleUUID());
            // 好像还缺少个用户名,用"exam_user_手机号"来注册：需要校验唯一性数据字段已经设置unique了，失败会异常地
            String defaultUsername = "wisUser";
            wisUser.setUserUsername(registerDTO.getMobile());
            // 初始化昵称和用户名相同
            wisUser.setUserNickname(wisUser.getUserUsername());
            // 这里还需要进行加密处理，后续解密用Base64.decode()
            wisUser.setUserPassword(Base64.encode(registerDTO.getPassword()));
            // 默认设置为学生身份，需要老师和学生身份地话需要管理员修改
            wisUser.setUserRoleId(RoleEnum.STUDENT.getId());
            // 设置头像图片地址, 先默认一个地址，后面用户可以自己再改
            String defaultAvatar = "https://i.loli.net/2019/11/02/DvPiSRJrzoH1tkZ.gif";
            wisUser.setUserAvatar(defaultAvatar);
            // 设置描述信息，随便设置段默认的
            wisUser.setUserDescription("welcome to wisdom exam system");
            // 需要验证这个邮箱是不是已经存在：数据字段已经设置unique了，失败会异常地
            wisUser.setUserEmail(registerDTO.getEmail());
            // 需要验证手机号是否已经存在：数据字段已经设置unique了，失败会异常地
            wisUser.setUserPhone(registerDTO.getMobile());
            //这里去保存到数据库
            WisuserMapper.insert(wisUser);
            log.info("注册成功："+ wisUser);
            return wisUser;
        } catch (Exception e) {
            //如果上面插入数据库等出现了异常（因为有一些键是唯一的，所以会报错，所以
            log.info("注册失败，注意信息是否重复");
            return null;
            // 出异常，返回null，表示注册失败
        }

    }

    @Override
    public String login(LoginQo loginQo) {
        WisUser wisUser;
        QueryWrapper<WisUser> wrapper = new QueryWrapper<>();
        if (LoginTypeEnum.USERNAME.getType().equals(loginQo.getLoginType())) {
            // 登陆者用地是用户名
            wrapper.lambda()
                    .eq(WisUser::getUserUsername,loginQo.getUserInfo());
             wisUser = WisuserMapper.selectOne(wrapper);
        } else {
            // 登陆者用地是邮箱
            wrapper.lambda()
                    .eq(WisUser::getUserEmail,loginQo.getUserInfo());
            wisUser = WisuserMapper.selectOne(wrapper);
        }
        if (wisUser != null) {
            // 如果user不是null即能找到，才能验证用户名和密码
            // 数据库存的密码
            String passwordDb = Base64.decodeStr(wisUser.getUserPassword());
            // 用户请求参数中的密码
            String passwordQo = loginQo.getPassword();
            System.out.println(passwordDb);
            System.out.println(passwordQo);
            if (passwordQo.equals(passwordDb)) {
                // 如果密码相等地话说明认证成功,返回生成的token，有效期为一天
                //生成JWT令牌
//                Map<String, Object> claims=new HashMap<>();
//                claims.put(JwtClaimsConstant.USER_ID,wisUser.getUserId());
//                claims.put(JwtClaimsConstant.USER_NAME, wisUser.getUserUsername());
//                claims.put(JwtClaimsConstant.AVATAR, wisUser.getUserAvatar());
//                String toekn = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
                String token = JwtUtils.genJsonWebToken(wisUser);
                return token;
            }
        }
        return null;
    }

    @Override
    public WisUserVo getUserInfo(String userId) {
        WisUser wisUser = WisuserMapper.selectById(userId);
        WisUserVo wisUserVo = new WisUserVo();
        //产生断言：如果user为null则抛异常
        assert wisUser != null;
        //属性赋值给userVo
        BeanUtils.copyProperties(wisUser, wisUserVo);
        return wisUserVo;
    }

    @Override
    public WisUserInfoVo getInfo(String userId) {
        WisUser wisUser = WisuserMapper.selectById(userId);
        assert wisUser != null;
        WisUserInfoVo wisUserInfoVo = new WisUserInfoVo();
        // 1.尽可能的拷贝属性
        BeanUtils.copyProperties(wisUser, wisUserInfoVo);
        Integer roleId = wisUser.getUserRoleId();
        Role role = roleMapper.selectById(roleId);
        assert role != null;
        String roleName = role.getRoleName();

        // 2.设置角色名称:管理员、老师、学生
        wisUserInfoVo.setRoleName(roleName);

        // 3.设置当前用户的角色细节
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(role, roleVo);

        // 4.设置角色的可访问页面：
        String rolePageIds = role.getRolePageIds();
        String[] pageIdArr = rolePageIds.split("-");
        List<PageVo> pageVoList = new ArrayList<>();
        for (String pageIdStr : pageIdArr) {
            // 获取页面的id
            Integer pageId = Integer.parseInt(pageIdStr);

            // 4.1 向Role中添加Page
            PermissionPage page = permissionPageMapper.selectById(pageId);
            PageVo pageVo = new PageVo();
            BeanUtils.copyProperties(page, pageVo);

            // 4.2 向Page中添加action权限
            List<ActionVo> actionVoList = new ArrayList<>();
            String actionIdsStr = page.getActionIds();
            String[] actionIdArr = actionIdsStr.split("-");
            for (String actionIdStr : actionIdArr) {
                Integer actionId = Integer.parseInt(actionIdStr);
                Permission action = perssionMapper.selectById(actionId);
                ActionVo actionVo = new ActionVo();
                assert action != null;
                BeanUtils.copyProperties(action, actionVo);
                actionVoList.add(actionVo);
            }
            // 设置actionVoList到pageVo中，然后把pageVo加到pageVoList中
            pageVo.setActionVoList(actionVoList);
            // 设置pageVoList，下面再设置到RoleVo中
            pageVoList.add(pageVo);
        }
        // 设置PageVo的集合到RoleVo中
        roleVo.setPageVoList(pageVoList);
        // 最终把PageVo设置到UserInfoVo中，这样就完成了拼接
        wisUserInfoVo.setRoleVo(roleVo);
        return wisUserInfoVo;
    }
    //修改信息
    @Override
    public boolean changerUserInfo(WisUserDTO userDTO,String userId) {
        try {
            //获得之前的phone和email 便于根据这个去查询未修改前的aichat的userid，然后去更新他的phone
            WisUser wisUser = WisuserMapper.selectById(userId);
            String userOldPhone = wisUser.getUserPhone();
            String userOldEmail = wisUser.getUserEmail();
            UpdateWrapper<WisUser> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(WisUser::getUserId, userId);

            WisUser updatedUser = new WisUser();
            updatedUser.setUserNickname(userDTO.getUserNickname());
            updatedUser.setUserEmail(userDTO.getUserEmail());
            updatedUser.setUserPhone(userDTO.getUserPhone());
            updatedUser.setUserDescription(userDTO.getUserDescription());
            updatedUser.setUserAvatar(userDTO.getUserAvatar());
            // todo:这里保存用户信息到user表 使得保持一致 ：
            WisuserMapper.update(updatedUser, updateWrapper);
            //更新aiuserinfo
            changerAiUserInfo(userDTO,userOldPhone,userOldEmail);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    private void changerAiUserInfo(WisUserDTO userDTO,String userOldPhone,String userOldEmail) {
        //根据之前的phone和email去得到对应的id，然后再去修改
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getPhone,userOldPhone).or().eq(User::getEmail,userOldEmail);
        User aiOldUser = aiUserMapper.selectOne(queryWrapper);
        String userId = aiOldUser.getId();

        User aiUser=new User();
        aiUser.setNickname(userDTO.getUserNickname());
        aiUser.setPhone(userDTO.getUserPhone());
        aiUser.setEmail(userDTO.getUserEmail());
        aiUser.setAvatar(userDTO.getUserAvatar());

        UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
//        //由于这里的aichat和wisuser的id是不一样的，所以这里去获取
//        String aiUserId = AiUserIdContext.getAiUserIdContext();
        updateWrapper.lambda().eq(User::getId,userId);
        aiUserMapper.update(aiUser,updateWrapper);
    }
}
